/*
 * Copyright 2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.oschina.durcframework.easymybatis;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import net.oschina.durcframework.easymybatis.handler.FillHandler;

/**
 * 配置
 * 
 * @author tanghc
 */
public class EasymybatisConfig {

    public static String COUNT_EXPRESSION = "count(*)";

    private static final String GLOBAL_VM_PLACEHOLDER = "<!--_global_vm_-->";

    // 驼峰转换下划线
    private boolean camel2underline = Boolean.TRUE;
    // 生成mapper的线程池大小
    private int mapperExecutorPoolSize = 20;
    // 模板文件classpath
    private String templateClasspath;
    // 通用mapper路径
    private String commonSqlClasspath = "easymybatis/commonSql.xml";
    // mapper文件保存文件夹地址，如：C:/mapper
    private String mapperSaveDir;
    private String countExpression = COUNT_EXPRESSION;
    // 全局模板classpath
    private String globalVmLocation;
    // 逻辑删除,指定未删除时的值
    private String logicNotDeleteValue = "0";
    // 逻辑删除,删除后库数库据保存的值
    private String logicDeleteValue = "1";

    private List<FillHandler<?>> fillList = new ArrayList<>(8);

    public String getGlobalVmPlaceholder() {
        return GLOBAL_VM_PLACEHOLDER;
    }

    /**
     * 驼峰转换下划线，如果配置了true，则java字段映射成数据库字段将自动转成下划线形式
     * 
     * @param camel2underline
     */
    public void setCamel2underline(boolean camel2underline) {
        this.camel2underline = camel2underline;
    }

    /**
     * 是否执行驼峰转下划线. 如果配置了true，则java字段映射成数据库字段将自动转成下划线形式
     * 
     * @return
     */
    public boolean isCamel2underline() {
        return camel2underline;
    }

    public int getMapperExecutorPoolSize() {
        return mapperExecutorPoolSize;
    }

    public void setMapperExecutorPoolSize(int mapperExecutorPoolSize) {
        if (mapperExecutorPoolSize <= 0) {
            throw new IllegalArgumentException("mapperExecutorPoolSize必须大于0");
        }
        this.mapperExecutorPoolSize = mapperExecutorPoolSize;
    }

    public String getTemplateClasspath() {
        return templateClasspath;
    }

    public void setTemplateClasspath(String templateClasspath) {
        this.templateClasspath = templateClasspath;
    }

    public String getCommonSqlClasspath() {
        return commonSqlClasspath;
    }

    public void setCommonSqlClasspath(String commonSqlClasspath) {
        this.commonSqlClasspath = commonSqlClasspath;
    }

    public String getMapperSaveDir() {
        return mapperSaveDir;
    }

    /**
     * 将mapper文件保存到指定文件夹中<br>
     * 因为easymybatis是直接将mapper内容注入到内存当中，开发人员无感知，并且不知道mapper内容是什么样子<br>
     * 这个功能就是让开发人员能够查看到对应的mapper内容，方便定位和排查问题。<br>
     * 一般情况下此项不用开启。
     * 
     * @param mapperSaveDir
     *            mapper文件保存文件夹地址，如：C:/mapper
     */
    public void setMapperSaveDir(String mapperSaveDir) {
        File dir = new File(mapperSaveDir);
        boolean selfMake = false;
        if (!dir.exists()) {
            dir.mkdirs();
            selfMake = true;
        }
        if (!dir.isDirectory()) {
            if (selfMake) {
                dir.delete();
            }
            throw new IllegalArgumentException("mapperSaveDir必须是一个文件夹路径，mapperSaveDir：" + mapperSaveDir);
        }
        this.mapperSaveDir = mapperSaveDir;
    }

    /**
     * 设置字段填充
     * 
     * @param fills
     */
    public <T extends FillHandler<?>> void setFills(List<T> fills) {
        for (FillHandler<?> fill : fills) {
            fillList.add(fill);
        }

        Collections.sort(fillList, new Comparator<FillHandler<?>>() {
            @Override
            public int compare(FillHandler<?> o1, FillHandler<?> o2) {
                return Integer.compare(o1.getOrder(), o2.getOrder());
            }
        });
    }

    public FillHandler<?> getFill(Class<?> entityClass, Field field, String columnName) {
        for (FillHandler<?> fillHandler : fillList) {
            if (fillHandler.match(entityClass, field, columnName)) {
                return fillHandler;
            }
        }
        return null;
    }

    public void setCountExpression(String countExpression) {
        this.countExpression = countExpression;
    }

    public String getCountExpression() {
        return countExpression;
    }

    public String getGlobalVmLocation() {
        return globalVmLocation;
    }

    public void setGlobalVmLocation(String globalVmLocation) {
        this.globalVmLocation = globalVmLocation;
    }

    public String getLogicDeleteValue() {
        return logicDeleteValue;
    }

    public void setLogicDeleteValue(String logicDeleteValue) {
        this.logicDeleteValue = logicDeleteValue;
    }

    public String getLogicNotDeleteValue() {
        return logicNotDeleteValue;
    }

    public void setLogicNotDeleteValue(String logicNotDeleteValue) {
        this.logicNotDeleteValue = logicNotDeleteValue;
    }

}
